using System;
using System.Collections.Generic;
using ImageProcessing.Common;

namespace ImageProcessing.PointsSampler
{
    class SteppedPointsSampler : IInterestPointSampler
    {
        private const int MaxDescriptorTime = 700;
        private const int MinPointsDescriptor = 20;
        public int MaxPointsDescriptor { get; set; }

        public SteppedPointsSampler()
        {
            MaxPointsDescriptor = 50;
        }

        protected readonly List<InterestPoint> ProcessedIpts = new List<InterestPoint>();

        public IEnumerable<InterestPoint> GetSamplePoints(long descriptorTimeLength, List<InterestPoint> ipts, List<InterestPoint> lastMatchedIpts)
        {
            var iptsCount = ipts.Count;
            var lastProcessIptsCount = ProcessedIpts.Count;

            ProcessedIpts.Clear();

            var numberOfPointsToScan = (int)CalcNumberOfPointsToCheck(lastProcessIptsCount, descriptorTimeLength);

            if (numberOfPointsToScan == 1000 || numberOfPointsToScan == 0)
                numberOfPointsToScan = Math.Max(MinPointsDescriptor, (int)(lastProcessIptsCount * 0.7f));

            numberOfPointsToScan = Math.Min(numberOfPointsToScan, MaxPointsDescriptor);

            SelectPoints(ipts, lastMatchedIpts, numberOfPointsToScan, iptsCount);

            return ProcessedIpts;
        }

        protected virtual void SelectPoints(List<InterestPoint> ipts, List<InterestPoint> lastMatchedIpts, int numberOfPointsToScan, int iptsCount)
        {
            var offset = Math.Max(iptsCount / numberOfPointsToScan, 1);
            numberOfPointsToScan = Math.Min(numberOfPointsToScan, iptsCount);

            for (var i = 0; i < numberOfPointsToScan; i++)
            {
                ProcessedIpts.Add(ipts[i * offset]);
            }
        }

        private long CalcNumberOfPointsToCheck(int lastPointsDone, long descriptorTimeLength)
        {
            return MaxDescriptorTime / ((descriptorTimeLength / Math.Max(1, lastPointsDone)) + 1);
        }
    }
}